#include "database/folder_repository.h"
#include "database/file_system_status.h"
#include <QDebug>
#include <QSet>
#include <QMap>
#include <QPair>
#include <QJsonObject>
#include <QJsonValue>

FolderRepository::FolderRepository(QSqlDatabase &database, const QString &currentUserId)
    : m_database(database)
    , m_currentUserId(currentUserId)
{
}

bool FolderRepository::isDatabaseConnected() const
{
    return m_database.isOpen() && m_database.isValid();
}

KmsFolder FolderRepository::mapFromQuery(const QSqlQuery &query) const
{
    KmsFolder folder;
    folder.id = query.value("ID").toString();
    folder.name = query.value("NAME").toString();
    folder.diskId = query.value("DISK_ID").toString();
    folder.folderId = query.value("FOLDER_ID").toString();
    folder.path = query.value("PATH").toString();
    folder.creator = query.value("CREATOR").toString();
    folder.creatorId = query.value("CREATOR_ID").toString();
    folder.type = query.value("TYPE").toInt();
    folder.createDate = query.value("CREATE_DATE").toString();
    folder.lastModifyDate = query.value("LAST_MODIFY_DATE").toString();
    folder.orderNo = query.value("ORDER_NO").toInt();
    folder.removeOperator = query.value("REMOVE_OPERATOR").toString();
    folder.status = query.value("STATUS").toInt();
    folder.version = query.value("VERSION").toInt();
    folder.maxVersion = query.value("MAX_VERSION").toInt();
    folder.userId = query.value("USER_ID").toString();
    return folder;
}

bool FolderRepository::insert(const KmsFolder &folder)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("INSERT INTO kms_folder (ID, NAME, DISK_ID, FOLDER_ID, PATH, CREATOR, "
                  "CREATOR_ID, TYPE, CREATE_DATE, LAST_MODIFY_DATE, ORDER_NO, REMOVE_OPERATOR, "
                  "STATUS, VERSION, MAX_VERSION, USER_ID) "
                  "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
    
    query.addBindValue(folder.id);
    query.addBindValue(folder.name);
    query.addBindValue(folder.diskId);
    query.addBindValue(folder.folderId);
    query.addBindValue(folder.path);
    query.addBindValue(folder.creator);
    query.addBindValue(folder.creatorId);
    query.addBindValue(folder.type);
    query.addBindValue(folder.createDate);
    query.addBindValue(folder.lastModifyDate);
    query.addBindValue(folder.orderNo);
    query.addBindValue(folder.removeOperator);
    query.addBindValue(folder.status);
    query.addBindValue(folder.version);
    query.addBindValue(folder.maxVersion);
    QString userId = folder.userId.isEmpty() ? m_currentUserId : folder.userId;
    query.addBindValue(userId);
    
    if (!query.exec()) {
        qDebug() << "插入文件夹记录失败:" << query.lastError().text();
        return false;
    }
    
    return true;
}

bool FolderRepository::update(const KmsFolder &folder)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_folder SET NAME=?, DISK_ID=?, FOLDER_ID=?, PATH=?, CREATOR=?, "
                  "CREATOR_ID=?, TYPE=?, CREATE_DATE=?, LAST_MODIFY_DATE=?, ORDER_NO=?, REMOVE_OPERATOR=?, "
                  "STATUS=?, VERSION=?, MAX_VERSION=? "
                  "WHERE ID=?");
    
    query.addBindValue(folder.name);
    query.addBindValue(folder.diskId);
    query.addBindValue(folder.folderId);
    query.addBindValue(folder.path);
    query.addBindValue(folder.creator);
    query.addBindValue(folder.creatorId);
    query.addBindValue(folder.type);
    query.addBindValue(folder.createDate);
    query.addBindValue(folder.lastModifyDate);
    query.addBindValue(folder.orderNo);
    query.addBindValue(folder.removeOperator);
    query.addBindValue(folder.status);
    query.addBindValue(folder.version);
    query.addBindValue(folder.maxVersion);
    query.addBindValue(folder.id);
    
    if (!query.exec()) {
        qDebug() << "更新文件夹记录失败:" << query.lastError().text();
        return false;
    }
    
    return true;
}

bool FolderRepository::remove(const QString &folderId)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return false;
    }
    
    if (folderId.isEmpty()) {
        qDebug() << "文件夹ID为空，无法删除";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("DELETE FROM kms_folder WHERE ID = ?");
    query.addBindValue(folderId);
    
    if (!query.exec()) {
        qDebug() << "删除文件夹记录失败:" << query.lastError().text();
        return false;
    }
    
    if (query.numRowsAffected() > 0) {
        qDebug() << "成功删除文件夹记录，文件夹ID:" << folderId;
        return true;
    } else {
        qDebug() << "未找到匹配的文件夹记录，文件夹ID:" << folderId;
        return false;
    }
}

KmsFolder FolderRepository::findById(const QString &folderId)
{
    KmsFolder folder;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return folder;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_folder WHERE ID = ?");
    query.addBindValue(folderId);
    
    if (!query.exec()) {
        qDebug() << "根据ID查询文件夹记录失败:" << query.lastError().text();
        return folder;
    }
    
    if (query.next()) {
        folder = mapFromQuery(query);
    }
    
    return folder;
}

KmsFolder FolderRepository::findByExactPath(const QString &path)
{
    KmsFolder folder;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return folder;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_folder WHERE PATH = ?");
    query.addBindValue(path);
    
    if (!query.exec()) {
        qDebug() << "精确查询文件夹记录失败:" << query.lastError().text();
        return folder;
    }
    
    if (query.next()) {
        folder = mapFromQuery(query);
    }
    
    return folder;
}

QList<KmsFolder> FolderRepository::findByPath(const QString &path)
{
    QList<KmsFolder> folders;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return folders;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_folder WHERE PATH LIKE ?");
    query.addBindValue("%" + path + "%");
    
    if (!query.exec()) {
        qDebug() << "查询文件夹记录失败:" << query.lastError().text();
        return folders;
    }
    
    while (query.next()) {
        folders.append(mapFromQuery(query));
    }
    
    return folders;
}

QList<KmsFolder> FolderRepository::findAll()
{
    QList<KmsFolder> folders;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return folders;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_folder");
    
    if (!query.exec()) {
        qDebug() << "查询所有文件夹记录失败:" << query.lastError().text();
        return folders;
    }
    
    while (query.next()) {
        folders.append(mapFromQuery(query));
    }
    
    return folders;
}

QList<KmsFolder> FolderRepository::findSubFoldersByFolderId(const QString &folderId)
{
    QList<KmsFolder> folders;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return folders;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_folder WHERE FOLDER_ID = ?");
    query.addBindValue(folderId);
    
    if (!query.exec()) {
        qDebug() << "查询子文件夹失败:" << query.lastError().text();
        return folders;
    }
    
    while (query.next()) {
        folders.append(mapFromQuery(query));
    }
    
    return folders;
}

QList<KmsFile> FolderRepository::findSubFilesByFolderId(const QString &folderId)
{
    QList<KmsFile> files;
    
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接";
        return files;
    }
    
    QSqlQuery query(m_database);
    query.prepare("SELECT * FROM kms_file WHERE FOLDER_ID = ?");
    query.addBindValue(folderId);
    
    if (!query.exec()) {
        qDebug() << "查询子文件失败:" << query.lastError().text();
        return files;
    }
    
    while (query.next()) {
        KmsFile file;
        file.id = query.value("ID").toString();
        file.name = query.value("NAME").toString();
        file.diskId = query.value("DISK_ID").toString();
        file.folderId = query.value("FOLDER_ID").toString();
        file.creator = query.value("CREATOR").toString();
        file.creatorId = query.value("CREATOR_ID").toString();
        file.type = query.value("TYPE").toString();
        file.createDate = query.value("CREATE_DATE").toString();
        file.lastModifyDate = query.value("LAST_MODIFY_DATE").toString();
        file.originType = query.value("ORIGIN_TYPE").toInt();
        file.originId = query.value("ORIGIN_ID").toString();
        file.size = query.value("SIZE").toLongLong();
        file.removeOperator = query.value("REMOVE_OPERATOR").toString();
        file.status = query.value("STATUS").toInt();
        file.checksum = query.value("CHECKSUM").toString();
        file.localFileSize = query.value("LOCAL_FILE_SIZE").toLongLong();
        file.localFileChecksum = query.value("LOCAL_FILE_CHECKSUM").toString();
        file.localFilePath = query.value("LOCAL_FILE_PATH").toString();
        file.userId = query.value("USER_ID").toString();
        files.append(file);
    }
    
    return files;
}


bool FolderRepository::updateStatus(const QString &folderId, int status)
{
    if (!isDatabaseConnected()) {
        qDebug() << "数据库未连接，无法更新文件夹状态";
        return false;
    }
    
    if (folderId.isEmpty()) {
        qDebug() << "文件夹ID为空，无法更新状态";
        return false;
    }
    
    QSqlQuery query(m_database);
    query.prepare("UPDATE kms_folder SET STATUS = ? WHERE ID = ?");
    query.addBindValue(status);
    query.addBindValue(folderId);
    
    if (!query.exec()) {
        qDebug() << "更新文件夹状态失败:" << query.lastError().text();
        return false;
    }
    
    qDebug() << "成功更新文件夹" << folderId << "状态为:" << status;
    return true;
}

bool FolderRepository::syncFromJson(const QJsonArray &foldersData)
{
    if (!m_database.isOpen()) {
        qDebug() << "数据库未打开，无法同步文件夹数据";
        return false;
    }
    
    try {
        m_database.transaction();
        
        // 查询现有文件夹记录，包括 ID, VERSION, STATUS
        QMap<QString, QPair<int, int>> existingFolders; // key: folderId, value: <version, status>
        QSqlQuery selectQuery(m_database);
        if (selectQuery.exec("SELECT ID, VERSION, STATUS FROM kms_folder")) {
            while (selectQuery.next()) {
                QString id = selectQuery.value(0).toString();
                int version = selectQuery.value(1).toInt();
                int status = selectQuery.value(2).toInt();
                existingFolders[id] = QPair<int, int>(version, status);
            }
        }
        
        // 准备 SQL 语句
        QSqlQuery insertQuery(m_database);
        insertQuery.prepare("INSERT INTO kms_folder (ID, NAME, CREATOR_ID, CREATOR, CREATE_DATE, LAST_MODIFY_DATE, DISK_ID, FOLDER_ID, PATH, TYPE, ORDER_NO, REMOVE_OPERATOR, VERSION, MAX_VERSION, STATUS, USER_ID) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        
        QSqlQuery updateQuery(m_database);
        updateQuery.prepare("UPDATE kms_folder SET NAME=?, CREATOR_ID=?, CREATOR=?, CREATE_DATE=?, LAST_MODIFY_DATE=?, DISK_ID=?, FOLDER_ID=?, PATH=?, TYPE=?, ORDER_NO=?, REMOVE_OPERATOR=?, VERSION=?, MAX_VERSION=?, STATUS=?, USER_ID=? WHERE ID=?");
        
        QSqlQuery updateStatusQuery(m_database);
        updateStatusQuery.prepare("UPDATE kms_folder SET STATUS=? WHERE ID=?");
        
        QSqlQuery deleteQuery(m_database);
        deleteQuery.prepare("DELETE FROM kms_folder WHERE ID=?");
        
        QSet<QString> processedFolderIds;
        int insertCount = 0;
        int updateCount = 0;
        int deleteCount = 0;
        int skipCount = 0;
        
        for (const QJsonValue &value : foldersData) {
            if (!value.isObject()) {
                qDebug() << "跳过非对象类型的文件夹数据";
                continue;
            }
            
            QJsonObject folderObj = value.toObject();
            
            QString id = folderObj["id"].toString();
            if (id.isEmpty()) {
                qDebug() << "跳过ID为空的文件夹数据";
                continue;
            }
            
            bool isDelete = folderObj["delete"].toBool(false);
            int serverVersion = folderObj["version"].toInt(0);
            
            processedFolderIds.insert(id);
            
            // 检查记录是否存在
            bool exists = existingFolders.contains(id);
            
            if (!isDelete) {
                // foldersData 有记录且 isDelete=false
                if (!exists) {
                    // kms_folder 表记录不存在，插入新记录，status=0（待下载）
                    QString name = folderObj["name"].toString();
                    QString creatorId = folderObj["creatorId"].toString();
                    QString creator = folderObj["creator"].toString();
                    QString createDate = folderObj["createDate"].toString();
                    QString lastModifyDate = folderObj["lastModifyDate"].toString();
                    QString diskId = folderObj["diskId"].toString();
                    QString folderId = folderObj["folderId"].toString();
                    QString path = folderObj["path"].toString();
                    QString removeOperator = folderObj["removeOperator"].toString();
                    int orderNo = folderObj["orderNo"].toInt();
                    int type = folderObj["type"].toInt();
                    int maxVersion = folderObj["maxVersion"].toInt(0);
                    
                    insertQuery.bindValue(0, id);
                    insertQuery.bindValue(1, name);
                    insertQuery.bindValue(2, creatorId);
                    insertQuery.bindValue(3, creator);
                    insertQuery.bindValue(4, createDate);
                    insertQuery.bindValue(5, lastModifyDate);
                    insertQuery.bindValue(6, diskId);
                    insertQuery.bindValue(7, folderId);
                    insertQuery.bindValue(8, path);
                    insertQuery.bindValue(9, type);
                    insertQuery.bindValue(10, orderNo);
                    insertQuery.bindValue(11, removeOperator);
                    insertQuery.bindValue(12, serverVersion);
                    insertQuery.bindValue(13, maxVersion);
                    insertQuery.bindValue(14, FileSystemStatus::PENDING_DOWNLOAD); // status = 待下载
                    insertQuery.bindValue(15, m_currentUserId);
                    
                    if (!insertQuery.exec()) {
                        qDebug() << "插入文件夹记录失败:" << insertQuery.lastError().text() << "文件夹ID:" << id;
                    } else {
                        insertCount++;
                    }
                } else {
                    // kms_folder 表记录存在
                    int existingVersion = existingFolders[id].first;
                    int existingStatus = existingFolders[id].second;
                    
                    if (serverVersion == existingVersion) {
                        // version 一致，不做处理
                        skipCount++;
                    } else if (serverVersion > existingVersion) {
                        // foldersData version > kms_folder version，需要更新
                        QString name = folderObj["name"].toString();
                        QString creatorId = folderObj["creatorId"].toString();
                        QString creator = folderObj["creator"].toString();
                        QString createDate = folderObj["createDate"].toString();
                        QString lastModifyDate = folderObj["lastModifyDate"].toString();
                        QString diskId = folderObj["diskId"].toString();
                        QString folderId = folderObj["folderId"].toString();
                        QString path = folderObj["path"].toString();
                        QString removeOperator = folderObj["removeOperator"].toString();
                        int orderNo = folderObj["orderNo"].toInt();
                        int type = folderObj["type"].toInt();
                        int maxVersion = folderObj["maxVersion"].toInt(0);
                        
                        int newStatus;
                        int newVersion;
                        if (FileSystemStatus::isPendingDelete(existingStatus)) {
                            // 原记录 status = 待提交删除，设置 status = 本地删除冲突
                            newStatus = FileSystemStatus::LOCAL_DELETE_CONFLICT;
                            // 保留本地版本
                            newVersion = existingVersion;
                        } else if (FileSystemStatus::isPendingDownload(existingStatus) || FileSystemStatus::isSynced(existingStatus)) {
                            // 原记录 status = 待下载 或 已同步，设置 status = 待下载
                            newStatus = FileSystemStatus::PENDING_DOWNLOAD;
                            // 使用服务器版本
                            newVersion = serverVersion;
                        } else if (FileSystemStatus::isPendingModify(existingStatus)) {
                            // 原记录 status = 待提交变更，设置 status = 变更冲突
                            newStatus = FileSystemStatus::MODIFY_CONFLICT;
                            // 保留本地版本
                            newVersion = existingVersion;
                        } else {
                            // 其他状态保持原状态或设置为待下载
                            newStatus = FileSystemStatus::PENDING_DOWNLOAD;
                            // 使用服务器版本
                            newVersion = serverVersion;
                        }
                        
                        updateQuery.bindValue(0, name);
                        updateQuery.bindValue(1, creatorId);
                        updateQuery.bindValue(2, creator);
                        updateQuery.bindValue(3, createDate);
                        updateQuery.bindValue(4, lastModifyDate);
                        updateQuery.bindValue(5, diskId);
                        updateQuery.bindValue(6, folderId);
                        updateQuery.bindValue(7, path);
                        updateQuery.bindValue(8, type);
                        updateQuery.bindValue(9, orderNo);
                        updateQuery.bindValue(10, removeOperator);
                        updateQuery.bindValue(11, newVersion);
                        updateQuery.bindValue(12, maxVersion);
                        updateQuery.bindValue(13, newStatus);
                        updateQuery.bindValue(14, m_currentUserId);
                        updateQuery.bindValue(15, id);
                        
                        if (!updateQuery.exec()) {
                            qDebug() << "更新文件夹记录失败:" << updateQuery.lastError().text() << "文件夹ID:" << id;
                        } else {
                            updateCount++;
                        }
                    }
                    // 如果 serverVersion < existingVersion，不做处理（本地版本更新）
                }
            } else {
                // foldersData 有记录且 isDelete=true
                if (!exists) {
                    // kms_folder 表记录不存在，不做处理
                    skipCount++;
                } else {
                    // kms_folder 表记录存在
                    int existingVersion = existingFolders[id].first;
                    int existingStatus = existingFolders[id].second;
                    
                    if (serverVersion > existingVersion) {
                        if (FileSystemStatus::isPendingDownload(existingStatus) || FileSystemStatus::isSynced(existingStatus)) {
                            // 原记录 status = 待下载 或 已同步，删除记录
                            deleteQuery.bindValue(0, id);
                            if (!deleteQuery.exec()) {
                                qDebug() << "删除文件夹记录失败:" << deleteQuery.lastError().text() << "文件夹ID:" << id;
                            } else {
                                deleteCount++;
                            }
                        } else if (FileSystemStatus::isPendingModify(existingStatus) || FileSystemStatus::isModifyConflict(existingStatus)) {
                            // 原记录 status = 待提交变更 或 变更冲突，设置 status = 服务器删除冲突
                            updateStatusQuery.bindValue(0, FileSystemStatus::SERVER_DELETE_CONFLICT);
                            updateStatusQuery.bindValue(1, id);
                            if (!updateStatusQuery.exec()) {
                                qDebug() << "更新文件夹状态失败:" << updateStatusQuery.lastError().text() << "文件夹ID:" << id;
                            } else {
                                updateCount++;
                            }
                        }
                        // 如果 existingStatus == 待提交删除，不做处理（本地已删除）
                    }
                    // 如果 serverVersion <= existingVersion，不做处理
                }
            }
        }
        
        m_database.commit();
        qDebug() << "同步文件夹数据完成 - 插入:" << insertCount << "更新:" << updateCount << "删除:" << deleteCount << "跳过:" << skipCount;
        return true;
        
    } catch (const std::exception &e) {
        qDebug() << "同步文件夹数据时发生异常:" << e.what();
        m_database.rollback();
        return false;
    } catch (...) {
        qDebug() << "同步文件夹数据时发生异常";
        m_database.rollback();
        return false;
    }
}

